package org.lds.scheduled.job.common.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.lds.scheduled.job.common.enums.ErrorEnum;
import org.lds.scheduled.job.common.exception.BusinessException;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

@Slf4j
public class RestUtil {
    private static final RestTemplate REST_TEMPLATE;

    static {
        OkHttp3ClientHttpRequestFactory requestFactory = new OkHttp3ClientHttpRequestFactory();
        requestFactory.setConnectTimeout(20000);
        requestFactory.setReadTimeout(60000);
        requestFactory.setWriteTimeout(20000);
        REST_TEMPLATE = new RestTemplate(requestFactory);
    }

    public static String post(String url, Object request) {
        return post(url, request, new ParameterizedTypeReference<String>() {});
    }

    public static <T> T post(String url, Object request, ParameterizedTypeReference<T> reference) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        HttpEntity httpEntity = new HttpEntity(request, headers);
        String wrapperUrl = wrapperUrl(url);

        T result = post(wrapperUrl, httpEntity, reference);
        log.info("请求地址:{} 请求参数:{} 响应结果:{}", wrapperUrl, request, result);
        return result;
    }

    private static String wrapperUrl(String url) {
        if (StringUtils.isEmpty(url)) return null;
        if (url.startsWith("http")) return url;
        return "http://" + url;
    }

    private static <T> T post(String url, HttpEntity httpEntity, ParameterizedTypeReference<T> reference) {
        try {
            return REST_TEMPLATE.exchange(url, HttpMethod.POST, httpEntity, reference).getBody();
        } catch (Exception e) {
            log.error("远程调用失败. 请求地址:{} 请求参数:{} 失败原因={}", url, httpEntity.getBody(), e.getMessage());
            throw new BusinessException(ErrorEnum.REST_FAIL);
        }
    }

}
